﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using WMS.HelperClasses;
using WHMS.HelperClasses;
using WHMS.EntityClasses;
using SD.LLBLGen.Pro.ORMSupportClasses;
using WHMS;

namespace WMS
{
	public partial class AddItemsForm : Form
	{
		TransactionEntity _currentTransaction;
		DepositTransactionEntity _currentDepositTransaction;		
		DataMngrFormBase<TransactionItemEntity> _tranItemsForm;
		List<ErrorProvider> _errorProviders;

		public AddItemsForm()
		{
			InitializeComponent();

            HideOrViewWeightCol();
		}

        private void HideOrViewWeightCol()
        {
            var weightCol = _transItemsGrid.Columns["Weight"];

            if (weightCol != null)
            {
                if (UserInfo.Roles.Where(r => r.ViewWorkshop == true).Count() > 0)
                {
                    weightCol.Visible = true;
                }
                else
                {
                    weightCol.Visible = false;
                }
            }
        }

		private void AddItemsForm_Load(object sender, EventArgs e)
		{			
			LoadData();

			_errorProviders = new List<ErrorProvider>();

			InitializeDataSources();
		}

		private void InitializeDataSources()
		{
			_currentTransaction = new TransactionEntity();
			_currentDepositTransaction = new DepositTransactionEntity();
			_currentDepositTransaction.Transaction = _currentTransaction;
			_transItems.RemovedEntitiesTracker = new EntityCollection<TransactionItemEntity>();

			BindDataSources();
			EnableDisableControls();
		}

		private void BindDataSources()
		{
			_TransBS.DataSource = _currentTransaction;
			_DepositBS.DataSource = _currentDepositTransaction;
		}

		void LoadData()
		{
			DALHelper.FetchCollection(_depositTypes, null, null, new SortExpression(DepositTypeFields.Order | SortOperator.Ascending));
			DALHelper.FetchCollection(_inspectionStatus, null, null, new SortExpression(InspectionTypeFields.Order | SortOperator.Ascending));

            //FormsHelper.LoadComboBox(SupplierDDL, SupplierFields.Id, SupplierFields.Name, (x, y) => DALHelper.GetDynamicList(x, y, null));
            //FormsHelper.LoadComboBox(ProjectsDDL, ProjectFields.Id, ProjectFields.Name, () => Business.GetRunningProjects());
			//FormsHelper.LoadComboBox(StoresDDL, StoreFields.Id, StoreFields.Name, ()=>Business.GetStoresForKeeper());
            //TODO
            //FormsHelper.CheckStoresAndProjects(StoresDDL.Items, ProjectsDDL.Items, new List<Control>() { _transItemsGrid, SaveBtn }, NoStoresLbl, NoProjectsLbl);

			StatusDDL.SelectedIndex = 0;
			TypeDDL.SelectedIndex = 0;
            GetShelves();
            //SupplierDDL.SelectedIndex = 0;
		}

		private void SaveBtn_Click(object sender, EventArgs e)
		{
            Save();
        }
        private void Save()
        {
			if (!ValidateForm())
				return;

			if (!_currentTransaction.IsNew)
			{
				if ((bool)DALHelper.GetValue(DepositTransactionFields.IsPriced, DepositTransactionFields.Id, _currentDepositTransaction.Id))
				{
					RetrieveTransaction();
					return;
				}
			}

			_currentTransaction.Type = "Deposit";
			_currentTransaction.CreatedBy = UserInfo.UserId;

			foreach(TransactionItemEntity item in _transItems)
			{
				item.StoreId = GetSelectedStoreId();
				_currentTransaction.TransactionItems.Add(item);
			}

			DALHelper.DeleteCollection(_transItems.RemovedEntitiesTracker);
			if (DALHelper.SaveEntity(_currentTransaction, true))
			{
				RetrieveTransaction();
				MessageBox.Show("تم الحفظ بنجاح.");
			}			
		}

		
		private bool ValidateForm()
		{
			var isValid = true;

			var controls = new List<TextBox>();
			controls.Add(PermitNumberTB);
			controls.Add(PRNumberTB);
			controls.Add(PONumberTB);
			controls.Add(SupplyOrderNumberTB);
            //controls.Add(SupplierTB);
			controls.Add(ExamRecordNumberTB);
			//controls.Add(BillOfLadingNmberTB);
			//controls.Add(PlateNumberTB);
			//controls.Add(DriverNameTB);

			if (_errorProviders == null)
			{
				_errorProviders = new List<ErrorProvider>();
			}
			else 
			{
				foreach (var errorProvider in _errorProviders)
				{
					errorProvider.Clear();
					errorProvider.Dispose();
				}
			}
			foreach (var tb in controls)
			{
				if (string.IsNullOrEmpty(tb.Text.Trim()))
				{
					var errorProvider = new ErrorProvider(this);
					_errorProviders.Add(errorProvider);

					errorProvider.SetError(tb, "يجب إدخال قيمة");
					errorProvider.RightToLeft = true;

					isValid = false;
					continue;
				}			
			}

			var combos = new List<ComboBox>();
			//combos.Add(StoresTB);
			combos.Add(TypeDDL);
			combos.Add(StatusDDL);

			foreach (var cmd in combos)
			{
				if (cmd.SelectedIndex < 0)
				{
					var errorProvider = new ErrorProvider(this);
					_errorProviders.Add(errorProvider);

					errorProvider.SetError(cmd, "يجب إختيار قيمة");
					errorProvider.RightToLeft = true;

					isValid = false;
				}
			}

			if (!ValidatePermitNumber())
				isValid = false;

            if (GetSelectedStoreId() == 0)
            {
                var errorProvider = new ErrorProvider(this);
                _errorProviders.Add(errorProvider);

                errorProvider.SetError(StoresTB, "يجب إدخال قيمة صحيحة ");
                errorProvider.RightToLeft = true;

                isValid = false;

            }


			_tranItemsForm.ValidateCollection();

			if (_transItems.Count <= 0)
			{
				isValid = false;
				MessageBox.Show("يجب إضافة أصناف", "خطأ فى الحفظ", MessageBoxButtons.OK, MessageBoxIcon.Error);
			}

			return isValid;
		}

		private bool ValidatePermitNumber()
		{
			return FormsHelper.ValidatePermitNumber(this, PermitNumberTB, _errorProviders, "Deposit", _currentTransaction.Id);
		}
		
        //private void StoresDDL_SelectedIndexChanged(object sender, EventArgs e)
        //{
        //    ResetTransactionItems();

        //    if (StoresDDL.SelectedItem == null)
        //        return;

        //    GetShelves();
        //}

		private void GetShelves()
		{
			var storeId = GetSelectedStoreId();
			_shelves.Clear();
			DALHelper.FetchCollection(_shelves, new RelationPredicateBucket(ShelfFields.StoreId == storeId));
		}
		
		private void ResetTransactionItems()
		{
			if (_tranItemsForm != null)
			{
				_tranItemsForm.Dispose();
				_tranItemsForm = null;
			}

			var label = new Label();
			_tranItemsForm = new DataMngrFormBase<TransactionItemEntity>(_transItems, _transItemsGrid, _itemsBS, new Button(), label, label, new RelationPredicateBucket(TransactionItemFields.TransactionId == 0));
			_tranItemsForm.SetNumericFields(new List<int> { 3 });
			_tranItemsForm.SetMandatoryFields(new List<int>() { 0, 1, 3 });
		}

		private int GetSelectedStoreId()
		{
            DataTable DTStore = Business.GetStoreDetails(StoresTB.Text);
            if (DTStore.Rows.Count > 0)
            {
                return Int32.Parse(DTStore.Rows[0][0].ToString());
            }

            return 0;
		}

        //private void ProjectsDDL_SelectedIndexChanged(object sender, EventArgs e)
        //{
        //    if (ProjectsDDL.SelectedItem == null)
        //        return;

        //    var projectId = (int)((System.Data.DataRowView)(ProjectsDDL.SelectedItem)).Row.ItemArray[0];
        //    Business.GetRawItemsPlannedForProject(projectId, _items);
        //}

		private void PermitNumberTB_Leave(object sender, EventArgs e)
		{
			ValidatePermitNumber();
		}

		private void RetrieveBtn_Click(object sender, EventArgs e)
		{
			RetrieveTransaction();
		}

		private void RetrieveTransaction()
		{
			if (string.IsNullOrEmpty(PermitNumberTB.Text.Trim()))
				return;

			var collection = new EntityCollection<TransactionEntity>();
			var prefetch = new PrefetchPath2(EntityType.TransactionEntity);
			prefetch.Add(TransactionEntity.PrefetchPathDepositTransactions);

			var filter = new RelationPredicateBucket(TransactionFields.Type == "Deposit");

            //Added by Thabet 
            //retrieve only the all deposit transaction that bind with supply order (if its filled) 
            if (!string.IsNullOrEmpty(SupplyOrderNumberTB.Text))
            {
                filter.PredicateExpression.Add(new PredicateExpression(DepositTransactionFields.SupplyOrderNumber == SupplyOrderNumberTB.Text));
            }

			filter.PredicateExpression.Add(TransactionFields.PermitNumber == PermitNumberTB.Text.Trim());

			DALHelper.FetchCollection(collection, filter, prefetch);

			if (collection.Count <= 0 || collection[0].DepositTransactions.Count <= 0)
			{
				InitializeDataSources();
				return;
			}

			_currentTransaction = collection[0];
			_currentDepositTransaction = _currentTransaction.DepositTransactions[0];
			BindDataSources();
            
			_transItems.Clear();
			DALHelper.FetchCollection(_transItems, new RelationPredicateBucket(TransactionItemFields.TransactionId == _currentTransaction.Id));

            //Fill ItemName & ItemCode columns in retrieving transaction 
            if (_transItemsGrid.Rows.Count > 0)
            {
                for (int currentRow = 0; currentRow < _transItemsGrid.Rows.Count - 1; currentRow++)
                {
                    _transItemsGrid.Rows[currentRow].Cells[SequenceColumn.Index].Value = currentRow + 1;

                    int productItemId = Int32.Parse(_transItemsGrid.Rows[currentRow].Cells[ItemIdColumn.Index].Value.ToString());
                    GetItemDetailsByItemId(currentRow, productItemId);
                }

            }

            if (_transItems != null)
            {
                foreach (var transItem in _transItems)
                {
                    var itemCollection = new EntityCollection<ItemEntity>();

                    int itemId = ((TransactionItemEntity)(transItem)).ItemId;

                    var itemFilter = new RelationPredicateBucket(ItemFields.Id == itemId);

                    DALHelper.FetchCollection(itemCollection, itemFilter);

                    if (itemCollection.Count > 0)
                    {
                        ((TransactionItemEntity)(transItem)).Item = itemCollection[0];
                    }
                }
            }

            var supplierCollection = new EntityCollection<SupplierEntity>();
            var supplierFilter = new RelationPredicateBucket(SupplierFields.Id == _currentDepositTransaction.SupplierId);
            DALHelper.FetchCollection(supplierCollection, supplierFilter);
            SupplierTB.Text = supplierCollection[0].Code;

            var storeCollection = new EntityCollection<StoreEntity>();
            var storeFilter = new RelationPredicateBucket(StoreFields.Id == _currentTransaction.StoreId);
            DALHelper.FetchCollection(storeCollection, storeFilter);
            StoresTB.Text = storeCollection[0].Code;

            ValidatePermitNumber();
			EnableDisableControls();
		}

		void EnableDisableControls()
		{
            if (_currentDepositTransaction.TransactionStatus == 1)
            {
                _alreadyPricedLbl.Text = "* إذن الإضافه تم حفظه نهائيا ويمكن تسعيره فقط  !";
            }
            else if (_currentDepositTransaction.TransactionStatus == 2)
            {
                _alreadyPricedLbl.Text = "* إذن الإضافه تم تسعيره و لا يمكن تغيير بياناته !";
            }
            else
            {
                _alreadyPricedLbl.Text = String.Empty;
            }

            var isPriced = _currentDepositTransaction.IsPriced;
            var isSubmitted = _currentDepositTransaction.TransactionStatus > 0;

            var isEditable = !(isPriced || isSubmitted);

            _transItemsGrid.Enabled = isEditable;// !_currentDepositTransaction.IsPriced;
            SaveBtn.Enabled = isEditable;// !_currentDepositTransaction.IsPriced;
            btnSubmit.Enabled = isEditable;

            bindingNavigator1.Enabled = isEditable;// !_currentDepositTransaction.IsPriced;
            _alreadyPricedLbl.Visible = !isEditable;// !_currentDepositTransaction.IsPriced;

			StoresTB.Enabled = _currentTransaction.IsNew;
            //ProjectsDDL.Enabled = _currentTransaction.IsNew;
            ProjectsTB.Enabled = _currentTransaction.IsNew;
			NewBtn.Enabled = !_currentTransaction.IsNew;
            DeleteBtn.Enabled = !_currentTransaction.IsNew && isEditable; //!(_currentTransaction.IsNew || _currentDepositTransaction.IsPriced);
		}

		private void NewBtn_Click(object sender, EventArgs e)
		{
			InitializeDataSources();
			ResetTransactionItems();
            SupplierTB.Text = "";
            ProjectsTB.Text = "";
            StoresTB.Text = "";
		}

		private void _transItemsGrid_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
		{
            //Open the search form for products using code or name 
            if (e.ColumnIndex == ItemCodeColumn.Index)
            {
                var itemPickerForm = new ItemPickerForm(1);
                if (itemPickerForm.ShowDialog() == DialogResult.OK)
                {
                    GetItemDetailsByItemId(e.RowIndex, itemPickerForm.SelectedItemId);

                }
            }

            else if (e.ColumnIndex == quantityDataGridViewTextBoxColumn.Index)
            {

                var itemIdValue = _transItemsGrid.Rows[e.RowIndex].Cells[ItemIdColumn.Index].Value;
                if (itemIdValue == null)
                    return;

                var form = new UnitConverterForm((int)itemIdValue);
                if (form.ShowDialog() == DialogResult.OK)
                {
                    _transItemsGrid.SuspendLayout();
                    _transItemsGrid.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = form.Value;
                    _transItemsGrid.UpdateCellValue(e.ColumnIndex, e.RowIndex);
                    _transItemsGrid.ResumeLayout(true);
                }
            }
            _transItemsGrid.Refresh();
		}

		private void SearchBtn_Click(object sender, EventArgs e)
		{
			var filter = new RelationPredicateBucket(TransactionFields.Type == "Deposit");

            //Added by Thabet 
            //retrieve only the all deposit transaction that bind with supply order (if its filled) 
            if (!string.IsNullOrEmpty(SupplyOrderNumberTB.Text))
            {
                filter.PredicateExpression.Add(new PredicateExpression(DepositTransactionFields.SupplyOrderNumber == SupplyOrderNumberTB.Text));
            }

			filter.Relations.Add(TransactionEntity.Relations.ProjectEntityUsingProjectId);
			filter.Relations.Add(TransactionEntity.Relations.DepositTransactionEntityUsingTransactionId);
			filter.PredicateExpression.Add(
				new FieldCompareSetPredicate(DepositTransactionFields.SupplyOrderNumber, null, SupplyOrderFields.SupplyOrderNumber, null, SetOperator.In, null, true));

			var searchForm = new SearchForm(TransactionFields.PermitNumber, TransactionFields.ProjectId, TransactionFields.Date, filter, null);
			if (searchForm.ShowDialog() == DialogResult.OK)
			{
				PermitNumberTB.Text = searchForm.SelectedNumber;
				RetrieveTransaction();
			}
		}

		private void DeleteBtn_Click(object sender, EventArgs e)
		{
			var form = new DeleteConfirmationForm();

			if (form.ShowDialog() == DialogResult.Yes)
			{
				if (DALHelper.DeleteEntity(_currentTransaction))
				{
					InitializeDataSources();
					ResetTransactionItems();
				}
			}
		}


        /// <summary>
        /// Retrieve the data table represent item(Product) details based on ItemId
        /// Added by Thabet
        /// </summary>
        /// <param name="rowIndex"> Index of row in data grid</param>
        /// <param name="itemId">The ID of item(Product)</param>
        private void GetItemDetailsByItemId(int rowIndex, int itemId)
        {
            DataTable itemDT = Business.GetItemDetails(itemId);
            if (itemDT.Rows.Count <= 0)
                return;

            _transItemsGrid.Rows[rowIndex].Cells[ItemCodeColumn.Index].Value = itemDT.Rows[0][0].ToString();
            _transItemsGrid.Rows[rowIndex].Cells[ItemNameColumn.Index].Value = itemDT.Rows[0][1].ToString();

            _transItemsGrid.Rows[rowIndex].Cells[ItemIdColumn.Index].Value = itemId;

            return;
        }
        /// <summary>
        /// Retrieve the data table represent item(Product) details based on ItemCode
        /// Added by Thabet
        /// </summary>
        /// <param name="rowIndex">Index of row in data grid</param>
        /// <param name="itemCode">The code of item</param>
        private void GetItemDetailsByItemCode(int rowIndex, string itemCode)
        {
            var dt = Business.GetItemDetails(itemCode, 1);
            if (dt.Rows.Count <= 0)
                return;

            _transItemsGrid.Rows[rowIndex].Cells[ItemIdColumn.Index].Value = dt.Rows[0][0].ToString();
            _transItemsGrid.Rows[rowIndex].Cells[ItemNameColumn.Index].Value = dt.Rows[0][1].ToString();

            return;
        }

        private void _transItemsGrid_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            if (e.RowIndex < 0)
                return;

            if ((e.ColumnIndex == ItemCodeColumn.Index)&&(_transItemsGrid.Rows[e.RowIndex].Cells[ItemCodeColumn.Index].Value!=null))
            {
                string productItemCode = _transItemsGrid.Rows[e.RowIndex].Cells[ItemCodeColumn.Index].Value.ToString();
                GetItemDetailsByItemCode(e.RowIndex, productItemCode);
            }

            else if (e.ColumnIndex == quantityDataGridViewTextBoxColumn.Index)
            {
                var itemCollection = new EntityCollection<ItemEntity>();

                var itemId = ((TransactionItemEntity)(_transItems[e.RowIndex])).ItemId;

                var itemFilter = new RelationPredicateBucket(ItemFields.Id == itemId);

                DALHelper.FetchCollection(itemCollection, itemFilter);

                if (itemCollection.Count > 0)
                {
                    ((TransactionItemEntity)(_transItems[e.RowIndex])).Item = itemCollection[0];
                }
            }
        }

        private void _transItemsGrid_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e)
        {
            _transItemsGrid.Rows[e.RowIndex].Cells[SequenceColumn.Index].Value = e.RowIndex + 1;
        }

        private void btnSubmit_Click(object sender, EventArgs e)
        {
            var form = new SaveConfirmationForm();
            if (form.ShowDialog() == DialogResult.Yes)
            {
                _currentDepositTransaction.TransactionStatus = 1;
                Save();
                Business.StoreItems(GetSelectedStoreId(), _currentDepositTransaction, _currentTransaction);
            }
        }

        private void SearchSupplierBtn_Click(object sender, EventArgs e)
        {
            ResetTransactionItems();
            var filter = new RelationPredicateBucket();
            var searchForm = new fromGeneralEntityPicker("Supplier");
            if (searchForm.ShowDialog() == DialogResult.OK)
            {
                SupplierTB.Text = searchForm.SelectedItemCode;
                EnableDisableControls();
            }
        }

        private void SupplierTB_TextChanged(object sender, EventArgs e)
        {
            if (!String.IsNullOrEmpty(SupplierTB.Text))
            {
                DataTable supplierDT = Business.GetSupplierDetails(SupplierTB.Text.ToString());

                if (supplierDT != null && supplierDT.Rows.Count > 0)
                {
                    lblSupplier.Text = supplierDT.Rows[0]["Name"].ToString();
                    EnableDisableControls();
                }
                else
                {
                    lblSupplier.Text = string.Empty;
                }
            }
            else
            {
                lblSupplier.Text = string.Empty;
            }
        }

        private void ProjectsTB_TextChanged(object sender, EventArgs e)
        {
            if (!String.IsNullOrEmpty(ProjectsTB.Text))
            {
                ProjectEntity project = Business.GetProjectByCode(ProjectsTB.Text.ToString());

                if (project != null)
                {
                    lblProjectName.Text = project.Name;
                    ProjectsTB.Text = project.Code;
                    EnableDisableControls();
                    Business.GetSupplyOrderItemsPlannedForProject(project.Id, _items);
                    var filter = new RelationPredicateBucket();
                    filter.PredicateExpression.Add(new FieldCompareSetPredicate(ContractorFields.Id, null, ProjectContractorFields.ContractorId, null, SetOperator.In, new PredicateExpression(ProjectContractorFields.ProjectId == project.Id)));
                    ResetTransactionItems();
                    EnableDisableControls();
                }
                else
                {
                    lblProjectName.Text = string.Empty;
                }
            }
            else
            {
                lblProjectName.Text = string.Empty;
                //RunBtn.Enabled = false;
            }
        }

        private void SearchProjectBtn_Click(object sender, EventArgs e)
        {
            ResetTransactionItems();
            //var filter = new RelationPredicateBucket(ProjectFields.Id == _currentTransaction.ProjectId); //TODO
            var filter = new RelationPredicateBucket(ProjectFields.Status == "جارى");
            filter.PredicateExpression.Add(ProjectFields.IsGeneral == false);
            var searchForm = new SearchForm(ProjectFields.Code, ProjectFields.Name, ProjectFields.ActualStartDate, filter,
                                            () => Business.GetRunningProjects());
            if (searchForm.ShowDialog() == DialogResult.OK)
            {
                ProjectsTB.Text = searchForm.SelectedNumber;
                EnableDisableControls();
            }
        }

        private void StoresTB_TextChanged(object sender, EventArgs e)
        {
            if (!String.IsNullOrEmpty(StoresTB.Text))
            {
                DataTable DTStore = Business.GetStoreDetails(StoresTB.Text);
                if (DTStore.Rows.Count > 0)
                {
                    lblStoreName.Text = DTStore.Rows[0][2].ToString();
                    EnableDisableControls();
                }
                else
                {
                    lblStoreName.Text = string.Empty;
                    //RunBtn.Enabled = false;
                }
            }
            else
            {
                lblStoreName.Text = string.Empty;
                //RunBtn.Enabled = false;
            }

        }
	}
}
